/**
  ******************************************************************************
  * @file    usart.c
  * @author  armwind
  * @version V1.0
  * @date    2019.10.1
  * @brief   Main program body
  ******************************************************************************
  */

#include "usart.h"
#include "led.h"
#include "relay.h"

#define DEBUG_PORT USART1
#define USART1_REC_NUM 100

u8 receive_str[USART1_REC_NUM];     //接受缓冲
u8 uart_byte_count = 0;

#ifdef __GNUC__
  /* With GCC/RAISONANCE, small printf (option LD Linker->Libraries->Small printf
     set to 'Yes') calls __io_putchar() */
  #define PUTCHAR_PROTOTYPE int __io_putchar(int ch)
#else
  #define PUTCHAR_PROTOTYPE int fputc(int ch, FILE *f)
#endif /* __GNUC__ */
  
/* Private functions ---------------------------------------------------------*/
/**
  * @brief Configure the USART Device
  * @param  None
  * @retval None
  */
void usart_config(uint8_t port,  uint32_t BaudRate)
{ 
    USART_InitTypeDef USART_InitStructure;
    GPIO_InitTypeDef GPIO_InitStructure;
    NVIC_InitTypeDef NVIC_InitStructure;

    USART_TypeDef *InitPort = USART1;                           //默认是debug口
    RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOA, ENABLE);         //使能GPIOA的系统时钟

    if (port == 1) {
        RCC_APB2PeriphClockCmd (RCC_APB2Periph_USART1, ENABLE); //打开串口1串口时钟
        //GPIO MAP
        GPIO_PinAFConfig (GPIOA, GPIO_PinSource9, GPIO_AF_1);   //初始化GPIOA的PIN9为串口功能
        GPIO_PinAFConfig (GPIOA, GPIO_PinSource10, GPIO_AF_1);  //初始化GPIOA的PIN10为串口功能
        GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9 | GPIO_Pin_10; //初始化GPIOA PIN9,PIN10 口
        InitPort = USART1;
    } else if (port == 2) {
        RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART2, ENABLE);  //打开串口2串口时钟
        //GPIO MAP
        GPIO_PinAFConfig(GPIOA, GPIO_PinSource2, GPIO_AF_1);     //初始化GPIOA的PIN9为串口功能;

        GPIO_PinAFConfig(GPIOA, GPIO_PinSource3, GPIO_AF_1);     //初始化GPIOA的PIN9为串口功能;
        GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2 | GPIO_Pin_3;   //初始化GPIOA PIN9,PIN10 口
        InitPort = USART2;
    }
    USART_DeInit (InitPort);
    /* Configure pins as AF pushpull */
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;                //串口GPIO复用功能
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;              //推挽输出
    GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;
    GPIO_Init (GPIOA, &GPIO_InitStructure);

    USART_InitStructure.USART_BaudRate = BaudRate;                  //模特率设置
    USART_InitStructure.USART_WordLength = USART_WordLength_8b;     //数据长度为8bit
    USART_InitStructure.USART_StopBits = USART_StopBits_1;          //一个停止位
    USART_InitStructure.USART_Parity = USART_Parity_No;             //没有奇偶校验
    USART_InitStructure.USART_HardwareFlowControl =
            USART_HardwareFlowControl_None;                         //没有硬件流控，目前硬件没有引出
    USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx; //发送和接收工作模式

    USART_Init (InitPort, &USART_InitStructure);                    //串口使能
    USART_ITConfig(InitPort, USART_IT_RXNE, ENABLE);                //使能接收中断
    USART_Cmd (InitPort, ENABLE);

    /* USART1 IRQ Channel configuration */
    NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn;
    NVIC_InitStructure.NVIC_IRQChannelPriority = 0x01;
    NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
    NVIC_Init(&NVIC_InitStructure);
}

/**
  * @brief  Retargets the C library printf function to the USART.
  * @param  None
  * @retval None
  */
PUTCHAR_PROTOTYPE
{
  /* Place your implementation of fputc here */
  /* e.g. write a character to the USART */
  USART_SendData(DEBUG_PORT, (uint8_t) ch);

  /* Loop until transmit data register is empty */
  while (USART_GetFlagStatus(DEBUG_PORT, USART_FLAG_TXE) == RESET)
  {}

  return ch;
}

/**
  * @brief  Retargets the C library printf function to the USART.
  * @param  None
  * @retval None
  */
void uart1SendChar(u8 ch)
{
    while((USART1->ISR&0x40) == 0);
    USART1->TDR = (u8)ch;
}

/**
  * @brief  Retargets the C library printf function to the USART.
  * @param  None
  * @retval None
  */
void uart2SendChar(u8 ch)
{
    while((USART2->ISR&0x40) == 0);
    USART2->TDR = (u8)ch;
}

/**
  * @brief  Retargets the C library printf function to the USART.
  * @param  None
  * @retval None
  */
void uart2SendChars(u8 *str, u16 strlen)
{
    u16 k= 0 ;
    do {
        uart2SendChar(*(str + k));
        k++;
    } while (k < strlen);
}

void USART1_IRQHandler()
{
    u8 rec_data;

    if(USART_GetITStatus(DEBUG_PORT, USART_IT_RXNE) != RESET) { //判断是否有接受数据中断
        rec_data =(u8)USART_ReceiveData(DEBUG_PORT);
        if(rec_data == 'S') {                               //开始命令字符,紧接着的数据，即为正式的控制数据
            uart_byte_count = 0x01;
        } else if (rec_data == 'E') {                       //控制字的结尾发送过来
            if(strcmp("led_on",(char *)receive_str) == 0) {
                    led_set(LED_ON);                        //打开LED
            } else if(strcmp("led_off",(char *)receive_str) == 0) {
                    led_set(LED_OFF);                       //关闭LED
            } else if(strcmp("lrelay_on",(char *)receive_str) == 0) {
                    relay_ctrl(LEFT_RELAY, RELAY_ON);                 //打开左继电器
            } else if(strcmp("lrelay_off",(char *)receive_str) == 0) {
                    relay_ctrl(LEFT_RELAY, RELAY_OFF);                //关闭左继电器
            } else if(strcmp("rrelay_on",(char *)receive_str) == 0) {
                    relay_ctrl(RIGHT_RELAY, RELAY_ON);                //打开右继电器
            } else if(strcmp("rrelay_off",(char *)receive_str) == 0) {
                    relay_ctrl(RIGHT_RELAY, RELAY_OFF);               //关闭右继电器
            }
            //清楚接收缓存
            for(uart_byte_count = 0; uart_byte_count < 32; uart_byte_count++) {
                receive_str[uart_byte_count] = 0x00;
            }
            uart_byte_count = 0;
            //下面开始接受正式的控制数据
        } else if((uart_byte_count > 0) && (uart_byte_count <= USART1_REC_NUM)) {
            receive_str[uart_byte_count-1] = rec_data;
            uart_byte_count++;
        }
   }
}

/************************ (C) COPYRIGHT WEIDUWULIAN *****END OF FILE****/
